#include <iostream>
#include <cstring>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <pthread.h>

const int port = 8081;
const int n = 2;

void* Routine(void* arg)
{
    pthread_detach(pthread_self());
    int fd = *(int*)arg;
    delete (int*)arg;

    while(1)
    {
        std::cout << "socket " << fd << " is serving in the client" << std::endl;
        sleep(1);
    }

    return nullptr;
}


int main()
{
    int listen_sock = socket(AF_INET, SOCK_STREAM, 0);
    if(listen_sock < 0)
    {
        std::cerr << "socket fail" << std::endl;
        exit(1);
    }
    //端口复用:具体问题:
    int opt = 1;
    setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &(opt), sizeof(opt));

    struct sockaddr_in local;
    memset(&local, '\0', sizeof(local));
    local.sin_family = AF_INET;
    local.sin_port = htons(port);
    local.sin_addr.s_addr = INADDR_ANY;
    if(bind(listen_sock, (struct sockaddr*)&local, sizeof(local)) < 0)
    {
        std::cerr << "bind fail" << std::endl;
        exit(2);
    }

    if(listen(listen_sock, n) < 0)
    {
        std::cerr << "listen fail" << std::endl;
        exit(3);
    }

    struct sockaddr_in peer;
    socklen_t len = sizeof(peer);
    for(;;)
    {
        int sock = accept(listen_sock, (sockaddr*)&peer, &len);
        if(sock < 0)
        {
            std::cerr << "accpet fail" << std::endl;
            continue;
        }
        std::cout << "get a new link-> " << std::endl;
        int* p = new int(sock);

        pthread_t tid;
        pthread_create(&tid, nullptr, Routine, (void*)p);
    }
    return 0;
}